package com.example.mtblog.common.filter;


import cn.hutool.core.util.StrUtil;

import com.example.mtblog.common.Result;
import com.example.mtblog.common.data;
import com.example.mtblog.dto.LoginUser;

import com.example.mtblog.tool.SecurityUtils;
import com.example.mtblog.tool.TokenUtils;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

import lombok.extern.slf4j.Slf4j;
/**
 * token过滤器 验证token有效性
 * 这个过滤器通常被用于继承实现并在每次请求时只执行一次过滤
 * 此token不注入Spring，防止每次请求都走这个Filter
 */
//@Component
@Slf4j
public class TokenFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        LoginUser loginUser = null;

        String path = request.getServletPath();
        String role = data.getRole(path);

        loginUser = TokenUtils.getLoginUser(request,response);
        request.setAttribute("loginUser",loginUser);

        SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
        Date date = new Date(System.currentTimeMillis());


        if (!Objects.equals(role, "static")) {
            System.out.println("==================");
            System.out.println("请求接口 " + path);
            System.out.println("需要权限 " + role);
            System.out.println("Token " + request.getHeader("token"));
            System.out.println("请求用户 " + loginUser);
            System.out.println("请求时间 " + formatter.format(date));
            System.out.println("=================="+ "\n");
        }

        if(role == null || role.equals("static"))
        {
            chain.doFilter(request, response);
            return;
        }






        //Token解析失败或者权限不够  直接返回
        if(loginUser==null || loginUser.getRole().equals("user") && role.equals("admin")){
            System.out.println("**** " + path + " 请求失败****"+"\n");
            String message = StrUtil.format("没有权限访问:{}", request.getRequestURI());  // 错误信息
            SecurityUtils.renderJson(response, Result.noAuth(message));
            return;
        }





        Authentication authentication = SecurityUtils.getAuthentication();  // 从后端的上下文去获取用户权限验证信息


        //将用户授权的信息存入SecurityContextHolder，以便在后续过滤器中验证需要的登录才能访问但Token为空的请求
        if (Objects.isNull(authentication)) {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }





        chain.doFilter(request, response);

    }
}


